/*
   Copyright (c) 2019 Shanghai Xuanzi Technology Co. Ltd https://xuanzi.ltd
   XZMind is licensed under the Mulan PSL v1.
   You can use this software according to the terms and conditions of the Mulan PSL v1.
   You may obtain a copy of Mulan PSL v1 at:
      http://license.coscl.org.cn/MulanPSL
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
   PURPOSE.
   See the Mulan PSL v1 for more details.

*/


package xuanzi.xzmind.client;

import com.google.gwt.dom.client.CanvasElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;

import sbaike.client.h5.client.ElUtils;
import sbaike.client.h5.client.JQuery;
import xuanzi.commons.graphics.Color;
import xuanzi.commons.graphics.Paint;
import xuanzi.commons.graphics.SVGCanvas;
import xuanzi.h5.fs.core.IFile;
import xuanzi.h5.xzviews.client.View;
import xuanzi.h5.xzviews.client.ViewGroup;
import xuanzi.openmind.layout.Box;
import xuanzi.openmind.lines.Line;
import xuanzi.openmind.lines.RoundLine;
import xuanzi.openmind.nodes.Node;
import xuanzi.openmind.nodes.Sheet;
import xuanzi.openmind.renders.RenderBuffer;
import xuanzi.openmind.scenes.base.EastScene;
import xuanzi.openmind.scenes.base.NorthScene;
import xuanzi.openmind.scenes.base.Scene;
import xuanzi.openmind.scenes.base.SouthScene;
import xuanzi.openmind.scenes.base.ThinkTreeNorthScene;
import xuanzi.openmind.scenes.base.WestScene;
import xuanzi.openmind.shapes.Round;
import xuanzi.openmind.themes.Theme;

/**
 * 
 * 
 * @author 彭立铭
 *
 */
public class RenderView extends View implements xuanzi.h5.xzviews.client.FrameView.IView  {


	String title;
	
	public void setTitle(String title) {
		this.title = title;
	}
	
	public RenderView() { 
	}

	@Override
	public void onLoad(ViewGroup parent) { 
		ce = DOM.createElement("canvas").cast(); 
	}

	@Override
	public void onUnload() { 
		
	}
	
	public void setCode(String md) {
		
	}
	
	void onSave() {
		
	}
	
	public native void renderText(Element el, String id, String text)/*-{ 
		var $this = this; 
		var config = {
			supermind : {
				save:function(){
					 $this.@xuanzi.xzmind.client.RenderView::onSave()();
				},
				render : function(text) { 
					return $this.@xuanzi.xzmind.client.RenderView::supermind(Ljava/lang/String;)(text);
				}
			}, 
			tocm            : true,    // Using [TOCM]
            tocContainer    : "#custom-toc-container", // 自定义 ToC 容器层
			emoji : true,
			taskList : true,
			markdown : text ,
			tex : true,
			toc : true,
			codeFold : true,
			tocm : true,
			tocDropdown : true,
			flowChart : true,
			sequenceDiagram : true,
			syncScrolling : true,
			path : "editor.md/lib/"
		};
	 
		try {
		 
			this.editor = $wnd.editormd.markdownToHTML(id, config);
		 
		} catch (e) {
			console.dir(e);
		} 
	}-*/; 
	
	public void renderText(Element el, String id, int xheight,boolean dark, boolean md,String text) {
		
		render(el, id, xheight, dark, md, text);
	}
	
	native void render(Element el, String id, int xheight,boolean dark, boolean md,String text) /*-{ 
		var $this = this;
		var phone = false;
		var config = {
			supermind : {
				save:function(){
					 $this.@xuanzi.xzmind.client.RenderView::onSave()();
				},
				render : function(text) { 
					return $this.@xuanzi.xzmind.client.RenderView::supermind(Ljava/lang/String;)(text);
				}
			},
			editorTheme:dark?"blackboard":"default",
			previewTheme:dark?"dark":"default",
			theme:dark?"dark":"default",
			width : "99.8%",
			height : xheight - 60,
			emoji : true,
			taskList : true,
			markdown : text ,
			tex : true,
			toc : true,
			codeFold : true,
			tocm : true,
			tocDropdown : true,
			flowChart : true,
			sequenceDiagram : true,
			syncScrolling : true,
			path : "editor.md/lib/"
		};
	 
		try {
			if (md) {
				this.editor=$wnd.editormd.markdownToHTML(id, config);
			} else
				this.editor = $wnd.editormd(id, config);
		} catch (e) {
			console.dir(e);
		}
		this.editorId = id;
		this.editorConfig = config;
	}-*/;
	
	 
	public native void setMdText(String text) /*-{
		this.editor.setMarkdown(text);
	}-*/;
	 
	public native void setRenderText(String text) /*-{
		this.editorConfig.markdown = text;
		$wnd.editormd.markdownToHTML(this.editorId, this.editorConfig);
	}-*/;
	 
	public native String getMdText()/*-{
		return this.editor.getMarkdown();
	}-*/;
	 
	public void insertText(String text) { 
			insertMdText(text);
	}
	 
	public native void insertMdText(String text) /*-{
		this.editor.insertValue(text);
	}-*/;
	 
	public native void height(int height) /*-{
		this.editor.height(height);
	}-*/;
	
	/**
	 * 得到渲染后的文本
	 * @return
	 */ 
	public String getRenderedText() {
		StringBuffer sb = new StringBuffer("<html><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n" + 
				"    \r\n" + 
				"    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\r\n" + 
				"    <meta name=\"description\" content=\"使用玄子思维导图导出的《"+title+"》文档\"><head><title>"+title+"-玄子思维导图</title><link rel=\"stylesheet\" href=\"https://xzmind.xuanzi.ltd/editor.md/css/editormd.preview.min.css\"><link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min.css\"></head>\n<body>");
		sb.append("<div class=\"editormd-preview-container\"><div class=\"markdown-body\">\n");
		sb.append(JQuery.$(".editormd-preview-container").html());
		sb.append("\n</div><style>.editormd-html-preview, .editormd-preview-container{padding:0px}</style><hr/> <p>本文档使用 <a style=\"color:#666\" href=\"https://xzmind.xuanzi.ltd\">玄子思维导图</a> 导出</p></body>\n</html>");
		return sb.toString();
	}



CanvasElement ce ;

/**
 * 解析思维导图的接口方法
 * @param text	MD原文
 * @return 成功渲染的思维导图SVG
 */
public String supermind(String text) {
	Node root = parseText(text); 
	root.setShape(new Round());
	root.setLine(new RoundLine());
	Sheet sheet = new Sheet();
	sheet.setRoot(root);
	if(ce==null)
		ce = DOM.createElement("canvas").cast();
	SVGCanvas canvas = new SVGCanvas() {
		@Override
		public float textWidth(String text, boolean mline, Paint paint) {
			if(text==null)
				return 0; 
			ce.getContext2d().setFont(paint.textSize+"px 微软雅黑");
			return (float) ce.getContext2d().measureText(text).getWidth();
		}
	};
	sheet.setTheme(new Theme()); 
	RenderBuffer.canvas = canvas; 
	sheet.layoutChange(false); 
	Box bound = root.getScene().box();
	bound.inset(-10, -10);
	canvas.resize(bound.width(),bound.height());
	sheet.drawPicture(canvas);
	return canvas.toString();
}


/**
 * 解析MD原文格式
 * @param text2
 * @return
 */
public static Node parseText(String text2) {
	 
	pos = 1;
	
	Node root = new Node();
	root.setLine(new Line());
	
	String list[]=text2.split("\n");
	String first = list[0];
	Scene scene = new EastScene();
	if(first.startsWith(":")) {
		String key = first.substring(1); 
	
		if("逻辑图-向左".equals(key))
			scene = new WestScene();
		else if("思维树图".equals(key))
			scene = new ThinkTreeNorthScene();
		else if("组织架构图".equals(key))
			scene = new SouthScene();
		else if("组织架构图-向上".equals(key))
			scene = new NorthScene();
	
		first = list[1];
		pos = 2;
	} 
	root.setScene(scene);
	first= first.replace("\\n", "\n");
	if(first.startsWith("-")) {
		//root.setOpen(false);
		first.substring(1);
	}
//	root.applyStyle().textColor = 0xFF44ff33;	
	root.setTopic(first);
	if(first.contains(":")) {
		int p = first.indexOf(":");
		root.setLabel(first.substring(0,p));
		root.setTopic(first.substring(p+1));
	}
	
	listX(root, list , -1 );
	return root;
}

public static int level(String s) {
	if(s==null)
		return 0;
	for(int i=0;i<s.length();i++) {
		if(s.charAt(i)!=' ') {
			return i;
		}
	}
	return s.length();
}


static int pos = 0;
/**
 * 
 * @param node
 * @param list
 * @param plevel
 */
private static void listX(Node node,String[] list,int plevel ) {
	Node lastNode = node;
	
	while(pos<list.length){
		String topic = list[pos];
		if(topic==null||topic.trim().length()==0) {
			
		}else {
			int l = level(topic); 
			topic = topic.trim().replace("\\n", "\n");
			boolean open = true;
			if(topic.startsWith("---")) {
				open = false;
				topic = topic.substring(3);
			}
			Node child = new  Node(topic);
			int blank = topic.indexOf(" ");
			if(topic.startsWith(". ")) {
				topic = "● "+ topic.substring(2);
			}
			if(topic.startsWith("#")&&blank==7) {	//字体颜色
				try {
					String color = "#ff"+topic.substring(1,7);
					int c = Color.hex2int(color);
					child.applyStyle().textColor = c;
					child.applyStyle().borderColor = c;
					topic = topic.substring(8);
				}catch(Exception ex) {}
			}else if(topic.startsWith("##")&&blank==8) {	//背景颜色
				try {
					String color = "#ff"+topic.substring(2,8);
					int c = Color.hex2int(color);
					child.applyStyle().backgroundColor = c;
					child.applyStyle().borderColor = c;
					child.applyStyle().textColor = 0xFFFFFFFF - c+0xFF000000;
					topic = topic.substring(8);
				}catch(Exception ex) {}
			}else
			if(topic.startsWith("#### ")) {
				child.applyStyle().textSize = 16;
				topic = topic.substring(4);
			}else if(topic.startsWith("### ")) {
				child.applyStyle().textSize = 19;
				topic = topic.substring(3);
			}else if(topic.startsWith("## ")) {
				child.applyStyle().textSize = 22;
				topic = topic.substring(2);
			}else if(topic.startsWith("# ")) {
				child.applyStyle().textSize = 26;
				topic = topic.substring(1);
			}
			if(topic.contains(":")) {
				int p = topic.indexOf(":");
				child.setLabel(topic.substring(0,p));
				child.setTopic(topic.substring(p+1));
			}
			child.setTopic(topic);
			if(l>plevel) {  
				lastNode.addNode(child); 
				node = (Node) lastNode;
			}else if(l<plevel){
				int x = (plevel-l)/4;
				for(int i=0;i<x;i++) {
				 if(node.getParent()!=null)
				 	node = (Node) node.getParent();
				} 
				node.addNode(child);
			}else{  
				node.addNode(child); 
			}
			child.setOpen(open);
			lastNode = child;
			plevel = l;
		}
		pos++;
		
	}
}

@Override
public void onToolBarCreated(ElUtils toolbar) {
	// TODO Auto-generated method stub
	
}

@Override
public void onTitleBarCreated(ElUtils toolbar) {
	// TODO Auto-generated method stub
	
}

@Override
public void onActionCreated(ElUtils toolbar) {
	// TODO Auto-generated method stub
	
}

}
